/*
 * Project Name: jmax
 * File Name: RoomMonitor.java
 * Copyright: Copyright(C) 1985-2015 ZKTeco Inc. All rights reserved.
 */
package com.xdtech.hotel.protocol.manager;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

import com.thoughtworks.xstream.XStream;
import com.xdtech.common.service.impl.BaseService;
import com.xdtech.core.model.BaseModel;
import com.xdtech.hotel.model.Room;
import com.xdtech.hotel.monitor.ClientMonitor;
import com.xdtech.hotel.monitor.ComponentInfo;
import com.xdtech.hotel.monitor.RoomMonitorInfo;
import com.xdtech.hotel.protocol.vo.Ac;
import com.xdtech.hotel.protocol.vo.Dimmer;
import com.xdtech.hotel.protocol.vo.Music;
import com.xdtech.hotel.protocol.vo.Node;
import com.xdtech.hotel.protocol.vo.Tv;
import com.xdtech.hotel.util.HotelConstants;
import com.xdtech.hotel.util.RedisUtils;
import com.xdtech.hotel.vo.DeviceLinkItem;
import com.xdtech.hotel.vo.RoomItem;

/**
 * 
 * @author <a href="max.zheng@zkteco.com">郑志雄</>
 * @version TODO 添加版本
 * @see 相关类或方法，不需要请删除此行
 * @since 2015-4-8 下午5:23:03
 */
public class RoomMonitor
{
	private static Log log = LogFactory.getLog(RoomMonitor.class);
	public static Map<String, RoomMonitorInfo> monitorDatas = new ConcurrentHashMap();
	
//	public static void updateRoom(RoomMonitorInfo item) {
//		monitorDatas.put(item.getRoomNo(), item);
//	}
//	
	public static void removeRoom(String roomNo) {
//		RedisUtils.removeRoomInfo(roomNo);
		monitorDatas.remove(roomNo);
	}
//	
//	public static RoomMonitorInfo getRoomInfoByRoomNo(String roomNo)
//	{
//		return monitorDatas.get(roomNo);
//	}
	/**
	 * 初始化房间监控数据
	 * 
	 * @author max.zheng
	 * @since 2015-4-8 下午5:32:18
	 * @param baseService
	 */
	public static void initMonitorDatas(BaseService<BaseModel> baseService) {
		log.info("初始化房间监控数据......");
		Object obj = baseService.findByHql("from Room");
		List<Room> rooms = (List<Room>) obj;
		List<RoomItem> roomItems = RoomItem.createItems(rooms);
		for (RoomItem roomItem : roomItems)
		{
			updateMonitorRoomInfo(roomItem);
		}
		log.info("初始化房间监控数据......结束");
	}

	/**
	 * 更新房间监控信息到redis里
	 * @author max.zheng
	 * @create 2015-5-1下午5:22:24
	 * @modified by
	 * @param roomItem
	 * @return
	 */
	public static void updateMonitorRoomInfo(RoomItem roomItem) {
		RoomMonitorInfo roomMonitorInfo = new RoomMonitorInfo(roomItem.getId(), roomItem.getRoomNo(), roomItem.getStatus(), roomItem.getDeviceSn(),roomItem.getServiceArea(),roomItem.getType());
		roomMonitorInfo.setCustomer(roomItem.getCustomer());
		roomMonitorInfo.setOperationStatus(roomItem.getOperationStatus());
		roomMonitorInfo.setRoomFloor(roomItem.getFloor());
		List<DeviceLinkItem> deviceLinkItems = roomItem.getDeviceLinks();
		for (DeviceLinkItem deviceLinkItem : deviceLinkItems) {
			ComponentInfo componentInfo = new ComponentInfo();
			if(StringUtils.isBlank(deviceLinkItem.getComponent())) continue;
			
			if (HotelConstants.COMPONENT_MUSIC.equals(deviceLinkItem.getLtype()))
			{
				//音乐
				Music music = (Music)new XStream().fromXML(deviceLinkItem.getComponent());
//				componentInfo = new ComponentInfo(deviceLinkItem.getLtype(), music.getPower(),music.getAddr(),music.getChannel());
				componentInfo.createMusic(music.getAddr(), music.getChannel(), music.getPower(), music.getVolume(), music.getInput(), music.getCh());
			} else if (HotelConstants.COMPONENT_TV.equals(deviceLinkItem.getLtype()))
			{
				//电视
				Tv tv = (Tv)new XStream().fromXML(deviceLinkItem.getComponent());	
//				componentInfo = new ComponentInfo(deviceLinkItem.getLtype(), tv.getPower(),tv.getAddr(),tv.getChannel());
				componentInfo.createTv(tv.getAddr(), tv.getChannel(), tv.getPower(), tv.getVolume(), tv.getInput(), tv.getCh());
			} else if (HotelConstants.COMPONENT_AC.equals(deviceLinkItem.getLtype()))
			{
				//空调
				Ac ac = (Ac)new XStream().fromXML(deviceLinkItem.getComponent());
//				componentInfo = new ComponentInfo(deviceLinkItem.getLtype(), ac.getPower(),ac.getAddr(),ac.getChannel());
				componentInfo.createAc(ac.getAddr(), ac.getChannel(), ac.getPower(), ac.getMode(), ac.getFan(), ac.getTemp());
			} else if (HotelConstants.COMPONENT_DIMMER.equals(deviceLinkItem.getLtype()))
			{
				//电灯
				Dimmer dimmer = (Dimmer)new XStream().fromXML(deviceLinkItem.getComponent());	
//				componentInfo = new ComponentInfo(deviceLinkItem.getLtype(), dimmer.getStatus(),dimmer.getAddr(),dimmer.getChannel());
				componentInfo.createDimmer(dimmer.getAddr(), dimmer.getChannel(), dimmer.getStatus(), dimmer.getFreq(), dimmer.getDelay(), dimmer.getValue());
			}else if (HotelConstants.COMPONENT_NODE.equals(deviceLinkItem.getLtype()))
			{
				//开关节点
				Node node = (Node)new XStream().fromXML(deviceLinkItem.getComponent());	
				componentInfo.createNode(node.getAddr(), node.getChannel(), node.getStatus(), node.getFreq(), node.getDelay());
			}
			roomMonitorInfo.updateCompomentInfos(componentInfo);
		}
//		RedisUtils.setRoomInfo(roomMonitorInfo);
		//将放入redis改成内存
		monitorDatas.put(roomMonitorInfo.getRoomNo(), roomMonitorInfo);
		//添加到客户端房间监控数据
		ClientMonitor.addRoomMonitorData(roomMonitorInfo);
	}

	
	public void readStatus() {
		log.info("读取客房元件相关状态......");
		for (RoomMonitorInfo roomMonitorInfo : monitorDatas.values()) {
			if (DeviceMonitor.deviceIsOnline(roomMonitorInfo.getSn())) {
				//在线才发请求
				String rs = OperationManager.sendReadCmdToDevice(roomMonitorInfo.getSn(), roomMonitorInfo.getCompomentInfosMap().values());
				handlerReadResult(rs,roomMonitorInfo);
			}
		}
	}
	/**
	 * 
	 * @author max.zheng
	 * @create 2015-5-14下午8:51:11
	 * @modified by
	 * @param rs
	 * @param roomMonitorInfo
	 */
	private void handlerReadResult(String rs, RoomMonitorInfo roomMonitorInfo) {
		try {
			JSONObject result = new JSONObject(rs);
			String postSn = result.getString("SN");
			JSONArray ackr = result.getJSONArray("ack_r");
			JSONObject tempJson = null;
			for (int i = 0; i < ackr.length(); i++) {
				tempJson = ackr.getJSONObject(i);
				if (tempJson.has("SN")) {
					if (postSn.equals(tempJson.getString("SN"))) {
						//SN匹配错误
//						roomMonitorInfo.setOperationStatus(HotelConstants.ROOM_SN_ERROR_STATUS);
						break;
					}	
				}else {
					if (tempJson.has(HotelConstants.DEV_NODE_CONTROL)) {
						handlerNode(roomMonitorInfo,tempJson);
					}else if (tempJson.has(HotelConstants.DEV_AC_CONTROL)) {
						handlerAc(roomMonitorInfo,tempJson);
					}else if (tempJson.has(HotelConstants.DEV_DIMMER_CONTROL)) {
						handlerDimmer(roomMonitorInfo,tempJson);
					}else if (tempJson.has(HotelConstants.DEV_MUSIC_CONTROL)) {
						handlerMusic(roomMonitorInfo,tempJson);
					}else if (tempJson.has(HotelConstants.DEV_TV_CONTROL)) {
						handlerTv(roomMonitorInfo,tempJson);
					}else if (tempJson.has(HotelConstants.DEV_SCENE_CONTROL)) {
						handlerScene(roomMonitorInfo,tempJson);
					}else if (tempJson.has(HotelConstants.DEV_CARD_CONTROL)) {
						handlerCard(roomMonitorInfo,tempJson);
					}else if (tempJson.has(HotelConstants.DEV_TIME_CONTROL)) {
						handlerTime(roomMonitorInfo,tempJson);
					}
				}
			}
		} catch (Exception e) {
			
		}
		
	}
	/**
	 * 
	 * @author max.zheng
	 * @create 2015-5-14下午10:14:50
	 * @modified by
	 * @param roomMonitorInfo
	 * @param tempJson
	 * @throws Exception 
	 */
	private void handlerTime(RoomMonitorInfo roomMonitorInfo,
			JSONObject tempJson) throws Exception {
		JSONArray jsonArray = tempJson.getJSONArray(HotelConstants.DEV_TIME_CONTROL);
		for (int i = 0; i < jsonArray.length(); i++) {
			JSONObject nodeJson = jsonArray.getJSONObject(i);
			StringBuffer time = new StringBuffer();
			time.append(nodeJson.getString("year"))
				.append("-")
				.append(nodeJson.getString("month"))
				.append("-")
				.append(nodeJson.getString("day"))
				.append(" ")
				.append(nodeJson.getString("hour"))
				.append(":")
				.append(nodeJson.getString("minute"))
				.append(":")
				.append(nodeJson.getString("second"));
//			= nodeJson.getString("year")+"-"+nodeJson.getString("month")+"-"+nodeJson.getString("day")+" "
			roomMonitorInfo.setTime(time.toString());
		}
	}
	/**
	 * 
	 * @author max.zheng
	 * @create 2015-5-14下午10:14:45
	 * @modified by
	 * @param roomMonitorInfo
	 * @param tempJson
	 * @throws Exception 
	 */
	private void handlerScene(RoomMonitorInfo roomMonitorInfo,
			JSONObject tempJson) throws Exception {
		JSONArray jsonArray = tempJson.getJSONArray(HotelConstants.DEV_SCENE_CONTROL);
		for (int i = 0; i < jsonArray.length(); i++) {
			JSONObject nodeJson = jsonArray.getJSONObject(i);
			roomMonitorInfo.setScene(nodeJson.getString("number"));
		}
	}
	/**
	 * 
	 * @author max.zheng
	 * @create 2015-5-14下午10:06:20
	 * @modified by
	 * @param roomMonitorInfo
	 * @param tempJson
	 * @throws Exception 
	 */
	private void handlerTv(RoomMonitorInfo roomMonitorInfo, JSONObject tempJson) throws Exception {
		JSONArray jsonArray = tempJson.getJSONArray(HotelConstants.COMPONENT_TV);
		for (int i = 0; i < jsonArray.length(); i++) {
			JSONObject nodeJson = jsonArray.getJSONObject(i);
			ComponentInfo componentInfo = roomMonitorInfo.getCompomentInfosMap().get(nodeJson.getString("addr"));
			if (!nodeJson.getBoolean("success")) {
				//电视状态读取有误
				componentInfo.setPower("error");
			}else {
				componentInfo.setChannel(nodeJson.getString("channel"));
				componentInfo.setPower(nodeJson.getString("power"));
				componentInfo.setVolume(nodeJson.getString("volume"));
				componentInfo.setInput(nodeJson.getString("input"));
				componentInfo.setCh(nodeJson.getString("ch"));
			}
		}
	}
	/**
	 * 
	 * @author max.zheng
	 * @create 2015-5-14下午10:06:17
	 * @modified by
	 * @param roomMonitorInfo
	 * @param tempJson
	 * @throws Exception 
	 */
	private void handlerMusic(RoomMonitorInfo roomMonitorInfo,
			JSONObject tempJson) throws Exception {
		JSONArray jsonArray = tempJson.getJSONArray(HotelConstants.COMPONENT_MUSIC);
		for (int i = 0; i < jsonArray.length(); i++) {
			JSONObject nodeJson = jsonArray.getJSONObject(i);
			ComponentInfo componentInfo = roomMonitorInfo.getCompomentInfosMap().get(nodeJson.getString("addr"));
			if (!nodeJson.getBoolean("success")) {
				//电视状态读取有误
				componentInfo.setPower("error");
			}else {
				componentInfo.setChannel(nodeJson.getString("channel"));
				componentInfo.setPower(nodeJson.getString("power"));
				componentInfo.setVolume(nodeJson.getString("volume"));
				componentInfo.setInput(nodeJson.getString("input"));
				componentInfo.setCh(nodeJson.getString("ch"));
			}
		}
	}
	/**
	 * 
	 * @author max.zheng
	 * @create 2015-5-14下午10:06:14
	 * @modified by
	 * @param roomMonitorInfo
	 * @param tempJson
	 * @throws Exception 
	 */
	private void handlerDimmer(RoomMonitorInfo roomMonitorInfo,
			JSONObject tempJson) throws Exception {
		JSONArray jsonArray = tempJson.getJSONArray(HotelConstants.COMPONENT_DIMMER);
		for (int i = 0; i < jsonArray.length(); i++) {
			JSONObject nodeJson = jsonArray.getJSONObject(i);
			ComponentInfo componentInfo = roomMonitorInfo.getCompomentInfosMap().get(nodeJson.getString("addr"));
			if (!nodeJson.getBoolean("success")) {
				//电视状态读取有误
				componentInfo.setStatus("error");
			}else {
				componentInfo.setChannel(nodeJson.getString("channel"));
				componentInfo.setStatus(nodeJson.getString("status"));
				componentInfo.setFreq(nodeJson.getString("freq"));
				componentInfo.setDelay(nodeJson.getString("delay"));
				componentInfo.setValue(nodeJson.getString("value"));
			}
		}
	}
	/**
	 * 
	 * @author max.zheng
	 * @create 2015-5-14下午10:06:10
	 * @modified by
	 * @param roomMonitorInfo
	 * @param tempJson
	 */
	private void handlerCard(RoomMonitorInfo roomMonitorInfo,
			JSONObject tempJson) {
		
	}
	/**
	 * 
	 * @author max.zheng
	 * @create 2015-5-14下午10:01:37
	 * @modified by
	 * @param roomMonitorInfo
	 * @param tempJson
	 * @throws Exception 
	 */
	private void handlerAc(RoomMonitorInfo roomMonitorInfo, JSONObject tempJson) throws Exception {
		JSONArray jsonArray = tempJson.getJSONArray(HotelConstants.COMPONENT_AC);
		for (int i = 0; i < jsonArray.length(); i++) {
			JSONObject nodeJson = jsonArray.getJSONObject(i);
			ComponentInfo componentInfo = roomMonitorInfo.getCompomentInfosMap().get(nodeJson.getString("addr"));
			if (!nodeJson.getBoolean("success")) {
				//空调状态读取有误
				componentInfo.setPower("error");
			}else {
				componentInfo.setChannel(nodeJson.getString("channel"));
				componentInfo.setPower(nodeJson.getString("power"));
				componentInfo.setMode(nodeJson.getString("mode"));
				componentInfo.setFan(nodeJson.getString("fan"));
				componentInfo.setTemp(nodeJson.getString("temp"));
			}
		}
	}
	/**
	 * 
	 * @author max.zheng
	 * @create 2015-5-14下午9:23:04
	 * @modified by
	 * @param roomMonitorInfo
	 * @param tempJson
	 * @throws Exception 
	 */
	private void handlerNode(RoomMonitorInfo roomMonitorInfo,
			JSONObject tempJson) throws Exception {
		JSONArray jsonArray = tempJson.getJSONArray(HotelConstants.COMPONENT_NODE);
		for (int i = 0; i < jsonArray.length(); i++) {
			JSONObject nodeJson = jsonArray.getJSONObject(i);
			ComponentInfo componentInfo = roomMonitorInfo.getCompomentInfosMap().get(nodeJson.getString("addr"));
//			componentInfo = componentInfo==null?componentInfo
			if (!nodeJson.getBoolean("success")) {
				//节点状态读取有误
				componentInfo.setStatus("error");
			}else {
				componentInfo.setChannel(nodeJson.getString("channel"));
				componentInfo.setDelay(nodeJson.getString("delay"));
				componentInfo.setStatus(nodeJson.getString("status"));
				componentInfo.setFreq(nodeJson.getString("freq"));
			}
		}
	}

}
